package com.fjzx.androidframe.xlogger;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Abstract class that takes care of background threading the file log operation on Android.
 * implementing classes are free to directly perform I/O operations there.
 * <p>
 * Writes all logs to the disk with CSV format.
 *
 * @author xiongyongcong
 */
public class DiskLogStrategy implements LogStrategy {

    private final Handler handler;

    public DiskLogStrategy(Handler handler) {
        this.handler = Utils.checkNotNull(handler);
    }

    @Override
    public void log(int level, String tag, String message) {
        Utils.checkNotNull(message);
        handler.sendMessage(handler.obtainMessage(level, message));
    }

    static class WriteHandler extends Handler {
        private final String logPath;

        WriteHandler(Looper looper, String logPath) {
            super(Utils.checkNotNull(looper));
            this.logPath = Utils.checkNotNull(logPath);
        }

        @SuppressWarnings("checkstyle:emptyblock")
        @Override
        public void handleMessage(Message msg) {
            String content = (String) msg.obj;

            FileWriter fileWriter = null;
            File logFile = new File(logPath);

            try {
                fileWriter = new FileWriter(logFile, true);

                writeLog(fileWriter, content);

                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                if (fileWriter != null) {
                    try {
                        fileWriter.flush();
                        fileWriter.close();
                    } catch (IOException e1) { /* fail silently */ }
                }
            }
        }

        /**
         * This is always called on a single background thread.
         * Implementing classes must ONLY write to the fileWriter and nothing more.
         * The abstract class takes care of everything else including close the stream and catching IOException
         *
         * @param fileWriter an instance of FileWriter already initialised to the correct file
         */
        private void writeLog(FileWriter fileWriter, String content) throws IOException {
            Utils.checkNotNull(fileWriter);
            Utils.checkNotNull(content);

            fileWriter.append(content);
        }
    }
}
